package cn.lzm.system.service.impl;

import cn.lzm.basic.util.PageList;
import cn.lzm.org.domain.Employee;
import cn.lzm.system.domain.Menu;
import cn.lzm.system.domain.Permission;
import cn.lzm.system.domain.Role;
import cn.lzm.system.mapper.MenuMapper;
import cn.lzm.system.mapper.PermissionMapper;
import cn.lzm.system.mapper.RoleMapper;
import cn.lzm.system.query.RoleQuery;
import cn.lzm.system.service.IRoleService;
import cn.lzm.basic.service.impl.BaseServiceImpl;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.swagger2.mappers.EnumMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lzm
 * @since 2022-10-24
 */
@Service
public class RoleServiceImpl extends BaseServiceImpl<Role> implements IRoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private MenuMapper menuMapper;

    @Override
    @Transactional
    public void add(Role role) {
        // 先要创建角色到role表中  并且要返回主键的值
        roleMapper.add(role);
        init(role);
    }

    @Override
    @Transactional
    public void update(Role role) {
        roleMapper.update(role);
        init(role);
    }
    @Override
    @Transactional
    public void remove(Long id){
        roleMapper.delete(id);
        roleMapper.delPermissionRoleByRid(id);
        roleMapper.delMenuRoleByRid(id);
    }

    /**
     * 分页查询 返回普通字段 还 返回关联的权限id集合和菜单对象集合 为 修改角色时 权限和菜单回显提供数据
     * @param query
     * @return
     */
    @Override
    public PageList<Role> queryPage(RoleQuery query) {
        if (!StringUtils.isNullOrEmpty(query.getKeyword())) {
            query.setKeyword(query.getKeyword().trim());
        }
        Integer totals = roleMapper.queryByCount(query);
        if (null == totals || 0 == totals) {
            return new PageList<>(0, new ArrayList<>());
        }
        // 查询数据
        List<Role> roles = roleMapper.queryByPage(query);
//        List<Role> roleList = new ArrayList<>();
        // 获取查询到的角色对应的权限id集合和菜单对象集合
        getPermissionAndMenu(roles);

        return new PageList<>(totals, roles);
    }

    /**
     * 获取所有角色以及对应的权限和菜单
     * @param roles
     */
    private void getPermissionAndMenu(List<Role> roles) {
        for (Role role : roles) {
            List<Long> permissionIds = roleMapper.findPermissionRoleByRid(role.getId());
            if (permissionIds != null) {
                role.setPermissions(permissionIds);
            }
            List<Long> menuIds = roleMapper.findMenuRoleByRid(role.getId());
            // 通过权限id查出这些类 批量查
            if (menuIds != null){
                List<Menu> menus = menuMapper.findByIds(menuIds);

                if (menus != null) {
                    role.setMenush(menus);
                }
            } else {
                continue;
            }

        }
    }
    @Transactional
    private void init(Role role) {
        // 添加成功，添加关联表的【因为不知道是增加还是减少了权限和菜单所有，我们之间将相关权限全部删除，在进行添加】
        roleMapper.delPermissionRoleByRid(role.getId());
        roleMapper.delMenuRoleByRid(role.getId());
        // 删除完成后数据添加到相关表中
        // 【因为通过roleid进行添加所以这是一个参数，添加的数据也是一个参数，
        // 而且从前端传来的数组，后端使用集合接受的，所以会有两参数，需要使用@param给参数取别名】
        roleMapper.addPermissionRoleByRid(role.getId(), role.getPermissions());
        roleMapper.addMenuRoleByRid(role.getId(), role.getMenus());
    }
}
